#include "bigInt.h"

// Initialise le nombre n avec les chiffres contenus dans la chaîne
void initialiser(bigInt *n, char chaine[])
{
    int taille = strlen(chaine);
    int i = 0;
    n->taille = taille;

    n->tab = malloc(taille * sizeof(int));

    for(i = 0; i < taille; ++i)
    {
        n->tab[i] = chaine[i] - '0';
    }
}

// Initialise le nombre n dont le nombre de chiffres est taille à 0
void initialiserAZero(bigInt *n, int taille)
{
    int i = 0;
    n->tab = malloc(taille * sizeof(int));
    n->taille = taille;

    for(i = 0; i < taille; ++i)
        n->tab[i] = 0;
}

void inverser(bigInt *n)
{
    int i = 0;
    int j = (n->taille) - 1;
    int temp = 0;

    while(i < j)
    {
        temp = n->tab[i];
        n->tab[i] = n->tab[j];
        n->tab[j] = temp;

        i++;
        j--;
    }
}

// Copie les chiffres du nombre src dans le nombre dest à partir de la position indice
void copier(bigInt *src, int indice, bigInt *dest)
{
    int i = 0;
    for(i = 0; i < src->taille; ++i)
    {
        dest->tab[indice] = src->tab[i];
        indice++;
    }
}

// Additionne n1 et n2 (n1 >= n2) et range le résultat dans total
void addition(bigInt *n1, bigInt *n2, bigInt *total)
{
    bigInt a, b;
    int i = 0;
    int j = (n1->taille - n2->taille); // Au càs où n1 aurait des chiffres en plus que n2, ...

    int n = 0, resultat = 0, retenue = 0;

    initialiserAZero(&a, n1->taille);
    initialiserAZero(&b, (n2->taille) + j); // ...Réserver de la place correspondant au surplus dans b

    // Le calcul se fera avec a et b pour garder n1 et n2 intacts
    copier(n1, 0, &a);
    copier(n2, j, &b);

    // Je les inverse pour pouvoir faire l'addition dans le sens normal de la lecture du tableau
    inverser(&a);
    inverser(&b);

    initialiserAZero(total, n1->taille);

    for(i = 0; i < n1->taille; ++i)
    {
        n = a.tab[i] + b.tab[i] + retenue;
        resultat = n % 10;
        retenue = n / 10;

        total->tab[i] = resultat;
    }
	
    if(retenue != 0)
    {
	total->taille += 1;
        total->tab = realloc(total->tab, total->taille * sizeof(int));
        total->tab[total->taille - 1] = retenue;
    }

    // J'inverse le total pour avoir le résultat dans le sens normal de lecture d'un nombre
    inverser(total);

    liberer(&a);
    liberer(&b);
}
   
void afficher(bigInt *n)
{
    int i = 0;
    for(i = 0; i < n->taille; ++i)
    {
        printf("%d", n->tab[i]);
    }
    printf("\n");
}

void liberer(bigInt *n)
{
    free(n->tab);
}
